package my.guojian.jdbc.transaction;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import my.guojian.jdbc.bean.ConnectionBean;
import my.guojian.jdbc.connection.ConnectionPool;

/**
 * 事务管理器
 * 
 * @author guojian
 *
 */
public class TransactionManager {

	private static final Log log = LogFactory.getLog(TransactionManager.class);

	public static void beginTransaction() {
		TransactionUtil.transactionState.set(true);
	}

	public static void commitTransaction() {

		boolean exceptionState = TransactionUtil.exceptionState.get() == null ? false : true;
		if (exceptionState) {
			rollback();
		} else {
			commit();
		}
	}

	private static void commit() {
		List<ConnectionBean> conBeans = TransactionUtil.connectionBeanThread.get();
		if (conBeans == null) {
			return;
		}
		try {
			for (ConnectionBean connectionBean : conBeans) {
				Connection connection = connectionBean.getCon();
				connection.commit();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}

		try {
			closeStatementAndConnection();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static void rollback() {
		List<ConnectionBean> conBeans = TransactionUtil.connectionBeanThread.get();
		if (conBeans == null || conBeans.size() == 0) {
			return;
		}
		Iterator<ConnectionBean> conBeansIts = conBeans.iterator();
		while (conBeansIts.hasNext()) {
			ConnectionBean connectionBean = (ConnectionBean) conBeansIts.next();
			Connection connection = connectionBean.getCon();
			try {
				connection.rollback();
				log.debug("|=========================================================|");
				log.debug("|================transaction has rollback=================|");
				log.debug("|=========================================================|");
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		try {
			closeStatementAndConnection();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public static void closeStatementAndConnection() throws SQLException {
		List<Statement> statements = TransactionUtil.statementThread.get();
		List<ConnectionBean> conBeans = TransactionUtil.connectionBeanThread.get();
		if (statements != null) {
			Iterator<Statement> statementIts = statements.iterator();
			while (statementIts.hasNext()) {
				Statement statement = (Statement) statementIts.next();
				if (!statement.isClosed()) {
					statement.close();
				}
			}
		}

		if (conBeans != null) {
			Iterator<ConnectionBean> conBeansIts = conBeans.iterator();
			while (conBeansIts.hasNext()) {
				ConnectionBean connectionBean = (ConnectionBean) conBeansIts.next();
				ConnectionPool.closeConnection(connectionBean.getCon(), connectionBean.getTypeName(), null, null);
			}
		}

		TransactionUtil.connectionBeanThread.remove();
		TransactionUtil.statementThread.remove();
		TransactionUtil.transactionState.remove();
	}

}
